from manim import *


class drawTangent(Scene):
    """
    绘制函数y=x**2 图像, 并绘制每个点在图像上的切线
    """

    def draw_tangent_up(self, ax, x, y):
        derivative = 2 * x

        # 切线上一个点
        x1 = x - 1
        y1 = y - derivative
        # 切下下一个点
        x2 = x + 1
        y2 = y + derivative

        # 坐标轴上两个点, ax.c2p()将坐标值 转为 屏幕值
        start_point = ax.c2p(x1, y1)
        end_point = ax.c2p(x2, y2)
        tangent_line = Line(start_point, end_point)

        return tangent_line

    def construct(self):
        ax = Axes(
            x_range=[0, 5, 1],
            y_range=[0, 25, 10],
            # x_length=6,
            # y_length=6,
        )

        def func(x):
            # print(f"x={x}")
            return x**2

        graph = ax.plot(
            func,
            color=YELLOW,
            x_range=[0.0, 5.0, 0.2],
            # use_smoothing=False,
        )
        self.add(ax, graph)

        # 曲线的切线
        t = ValueTracker(1)
        line_tangent = Line()
        line_tangent.add_updater(
            lambda z: z.become(
                self.draw_tangent_up(ax, t.get_value(), func(t.get_value()))
            )
        )
        self.play(Create(line_tangent))

        # 点 延曲线移动
        dot = Dot()
        dot.add_updater(lambda x: x.move_to(ax.c2p(t.get_value(), func(t.get_value()))))
        dot.set_z_index(1)
        self.play(Create(dot))

        self.play(t.animate.set_value(5), run_time=5)
        self.wait()
